{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [],
   "metadata": {
    "collapsed": false
   },
   "id": "84cac76ea524cf0c"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "\n",
    "from langgraph.store.memory import InMemoryStore\n",
    "\n",
    "in_memory_store = InMemoryStore()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T03:25:21.312715Z",
     "start_time": "2024-11-11T03:25:21.309737Z"
    }
   },
   "id": "ead19677994a1baa",
   "execution_count": 58
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "from langchain_core.output_parsers import StrOutputParser\n",
    "import os\n",
    "from langchain_openai import ChatOpenAI\n",
    "from langgraph.checkpoint.memory import MemorySaver\n",
    "import uuid\n",
    "from langgraph.store.base import BaseStore\n",
    "from langchain_core.runnables import RunnableConfig\n",
    "from dotenv import load_dotenv\n",
    "from langgraph.constants import START, END\n",
    "from langgraph.graph import StateGraph, MessagesState\n",
    "\n",
    "load_dotenv()\n",
    "\n",
    "llm = ChatOpenAI(\n",
    "    openai_api_key=os.getenv(\"DASHSCOPE_API_KEY\"),\n",
    "    openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n",
    "    model_name=\"qwen-max\",\n",
    "    temperature=0\n",
    "    # stream_options={\"include_usage\":True},\n",
    ")\n",
    "\n",
    "class ReturnNodeValue:\n",
    "    def __init__(self, node_secret: str):\n",
    "        self._value = node_secret\n",
    "\n",
    "    def __call__(self, state: MessagesState, config: RunnableConfig, *, store: BaseStore):\n",
    "        # print(f\"ReturnNodeValue state: {state}\")\n",
    "        print(f\"ReturnNodeValue config: {config[\"configurable\"][\"user_id\"]}\")\n",
    "        # print(f\"Adding {self._value} to {state['aggregate']}\")\n",
    "        # return {\"aggregate\": [self._value]}\n",
    "\n",
    "\n",
    "# NOTE: we're passing the Store param to the node --\n",
    "# this is the Store we compile the graph with\n",
    "def call_model(state: MessagesState, config: RunnableConfig, *, store: BaseStore):\n",
    "    user_id = config[\"configurable\"][\"user_id\"]\n",
    "    namespace = (\"memories\", user_id)\n",
    "    print(f\"store: {store}\")\n",
    "    memories = store.search(namespace) if store else []\n",
    "    info = \"\\n\".join([d.value[\"data\"] for d in memories])\n",
    "    system_msg = f\"You are a helpful assistant talking to the user. User info: {info}\"\n",
    "\n",
    "    # Store new memories if the user asks the model to remember\n",
    "    last_message = state[\"messages\"][-1]\n",
    "    if \"remember\" in last_message.content.lower():\n",
    "        memory = \"User name is Bob\"\n",
    "        store.put(namespace, str(uuid.uuid4()), {\"data\": memory})\n",
    "    \n",
    "    # chain = llm|StrOutputParser()\n",
    "    response = llm.invoke(\n",
    "        [{\"type\": \"system\", \"content\": system_msg}] + state[\"messages\"]\n",
    "    )\n",
    "    print(f\"call_model: {response}\")\n",
    "    return {\"messages\": response}\n",
    "\n",
    "def call__(state: MessagesState, config: RunnableConfig, *, store: BaseStore):\n",
    "        # print(f\"ReturnNodeValue state: {state}\")\n",
    "        print(f\"ReturnNodeValue config: {config[\"configurable\"][\"user_id\"]}\")\n",
    "\n",
    "builder = StateGraph(MessagesState)\n",
    "builder.add_node(\"call_model\", call_model)\n",
    "builder.add_node(\"conversation_store\", ReturnNodeValue(\"conversation_store\"))\n",
    "builder.add_edge(START, \"call_model\")\n",
    "builder.add_edge(\"conversation_store\", END)\n",
    "builder.add_edge(\"call_model\", \"conversation_store\")\n",
    "\n",
    "memory_saver = MemorySaver()\n",
    "# NOTE: we're passing the store object here when compiling the graph\n",
    "graph = builder.compile(checkpointer=memory_saver, store=in_memory_store)\n",
    "# If you're using LangGraph Cloud or LangGraph Studio, you don't need to pass the store or checkpointer when compiling the graph, since it's done automatically.\n",
    "# from IPython.core.display import Image\n",
    "# \n",
    "# display(Image(graph.get_graph().draw_mermaid_png()))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T03:25:21.431555Z",
     "start_time": "2024-11-11T03:25:21.334953Z"
    }
   },
   "id": "395c6b3ff0a319c5",
   "execution_count": 59
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "store: <langgraph.store.memory.InMemoryStore object at 0x11e44d610>\n",
      "call_model: content=\"Hello Bob! It's nice to meet you. I'll do my best to remember your name going forward. Is there anything in particular you'd like to chat about today?\" additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 35, 'prompt_tokens': 35, 'total_tokens': 70, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'qwen-max', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-f72caed8-b428-4bea-8ad7-48c4493ffdbc-0' usage_metadata={'input_tokens': 35, 'output_tokens': 35, 'total_tokens': 70, 'input_token_details': {}, 'output_token_details': {}}\n",
      "ReturnNodeValue config: 1\n"
     ]
    }
   ],
   "source": [
    "from langchain_community.callbacks import get_openai_callback\n",
    "\n",
    "config = {\"configurable\": {\"thread_id\": \"1\", \"user_id\": \"1\"}}\n",
    "input_message = {\"type\": \"user\", \"content\": \"Hi! Remember: my name is Bob\"}\n",
    "with get_openai_callback() as cb:\n",
    "    graph.invoke({\"messages\": [input_message]}, config)\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T03:25:23.944145Z",
     "start_time": "2024-11-11T03:25:21.434601Z"
    }
   },
   "id": "34030db9bac2b6ae",
   "execution_count": 60
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Run the graph!\n",
    "\n",
    "线程1\n"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "75ce23ac40390aef"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "================================\u001B[1m Human Message \u001B[0m=================================\n",
      "\n",
      "Hi! Remember: my name is Bob\n",
      "store: <langgraph.store.memory.InMemoryStore object at 0x11e44d610>\n",
      "call_model: content='Hi Bob! I remember your name. How can I assist you today?' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 15, 'prompt_tokens': 91, 'total_tokens': 106, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'qwen-max', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-c4b508e8-e392-48cc-9e3c-bd8daa0ac624-0' usage_metadata={'input_tokens': 91, 'output_tokens': 15, 'total_tokens': 106, 'input_token_details': {}, 'output_token_details': {}}\n",
      "==================================\u001B[1m Ai Message \u001B[0m==================================\n",
      "\n",
      "Hi Bob! I remember your name. How can I assist you today?\n",
      "ReturnNodeValue config: 1\n"
     ]
    }
   ],
   "source": [
    "\n",
    "for chunk in graph.stream({\"messages\": [input_message]}, config, stream_mode=\"values\"):\n",
    "    chunk[\"messages\"][-1].pretty_print()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T03:25:25.599162Z",
     "start_time": "2024-11-11T03:25:23.945980Z"
    }
   },
   "id": "8e69b662e28aa1c7",
   "execution_count": 61
  },
  {
   "cell_type": "markdown",
   "source": [
    "线程2"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "e068a21e4db0eb0e"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "================================\u001B[1m Human Message \u001B[0m=================================\n",
      "\n",
      "what is my name?\n",
      "store: <langgraph.store.memory.InMemoryStore object at 0x11e44d610>\n",
      "call_model: content='Your name is Bob!' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 5, 'prompt_tokens': 40, 'total_tokens': 45, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'qwen-max', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-824e099c-701b-4565-a9e5-809c55674390-0' usage_metadata={'input_tokens': 40, 'output_tokens': 5, 'total_tokens': 45, 'input_token_details': {}, 'output_token_details': {}}\n",
      "==================================\u001B[1m Ai Message \u001B[0m==================================\n",
      "\n",
      "Your name is Bob!\n",
      "ReturnNodeValue config: 1\n"
     ]
    }
   ],
   "source": [
    "config = {\"configurable\": {\"thread_id\": \"2\", \"user_id\": \"1\"}}\n",
    "input_message = {\"type\": \"user\", \"content\": \"what is my name?\"}\n",
    "for chunk in graph.stream({\"messages\": [input_message]}, config, stream_mode=\"values\"):\n",
    "    chunk[\"messages\"][-1].pretty_print()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T03:25:26.348133Z",
     "start_time": "2024-11-11T03:25:25.603330Z"
    }
   },
   "id": "d81bcbb3e34a3e5c",
   "execution_count": 62
  },
  {
   "cell_type": "markdown",
   "source": [
    "现在，我们可以检查我们的内存存储，并验证我们确实为用户保存了记忆：\n"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "c9883ee14d6afbf5"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'value': {'data': 'User name is Bob'}, 'key': '54fa322d-4ded-4961-99a0-4bc575b845f7', 'namespace': ['memories', '1'], 'created_at': '2024-11-11T03:25:21.442347+00:00', 'updated_at': '2024-11-11T03:25:21.442352+00:00'}\n",
      "{'value': {'data': 'User name is Bob'}, 'key': '618e13f8-c548-46ff-9fa3-0e8522e3966e', 'namespace': ['memories', '1'], 'created_at': '2024-11-11T03:25:23.955496+00:00', 'updated_at': '2024-11-11T03:25:23.955502+00:00'}\n"
     ]
    }
   ],
   "source": [
    "for memory in in_memory_store.search((\"memories\", \"1\")):\n",
    "    print(memory.dict())"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T03:25:26.355295Z",
     "start_time": "2024-11-11T03:25:26.349951Z"
    }
   },
   "id": "37f2744cc87a190",
   "execution_count": 63
  },
  {
   "cell_type": "markdown",
   "source": [
    "现在，我们用另一个用户运行graph，以验证第一个用户的记忆是独立的。\n"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "35417959df3bc826"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "================================\u001B[1m Human Message \u001B[0m=================================\n",
      "\n",
      "what is my name?\n",
      "store: <langgraph.store.memory.InMemoryStore object at 0x11e44d610>\n",
      "call_model: content=\"I'm sorry, but I don't have access to your personal information, including your name. To protect your privacy and security, it's best not to share such details unless you choose to. If you'd like, you can tell me your name, and I'll do my best to assist you!\" additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 61, 'prompt_tokens': 32, 'total_tokens': 93, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'qwen-max', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-05043726-3a29-4b40-854a-b55793c237c9-0' usage_metadata={'input_tokens': 32, 'output_tokens': 61, 'total_tokens': 93, 'input_token_details': {}, 'output_token_details': {}}\n",
      "==================================\u001B[1m Ai Message \u001B[0m==================================\n",
      "\n",
      "I'm sorry, but I don't have access to your personal information, including your name. To protect your privacy and security, it's best not to share such details unless you choose to. If you'd like, you can tell me your name, and I'll do my best to assist you!\n",
      "ReturnNodeValue config: 2\n"
     ]
    }
   ],
   "source": [
    "config = {\"configurable\": {\"thread_id\": \"3\", \"user_id\": \"2\"}}\n",
    "input_message = {\"type\": \"user\", \"content\": \"what is my name?\"}\n",
    "for chunk in graph.stream({\"messages\": [input_message]}, config, stream_mode=\"values\"):\n",
    "    chunk[\"messages\"][-1].pretty_print()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T03:25:33.320914Z",
     "start_time": "2024-11-11T03:25:26.357500Z"
    }
   },
   "id": "a382c2e71cc3059",
   "execution_count": 64
  },
  {
   "cell_type": "markdown",
   "source": [
    "设置chatMode返回token使用统计，从graph获取状态及"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "15377515caf78823"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-----content='what is my name?' additional_kwargs={} response_metadata={} id='f3ded638-1e1a-4e9a-ac6f-e8f4b31c9f26'\n",
      "-----content=\"I'm sorry, but I don't have access to your personal information, including your name. To protect your privacy and security, it's best not to share such details unless you choose to. If you'd like, you can tell me your name, and I'll do my best to assist you!\" additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 61, 'prompt_tokens': 32, 'total_tokens': 93, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'qwen-max', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-05043726-3a29-4b40-854a-b55793c237c9-0' usage_metadata={'input_tokens': 32, 'output_tokens': 61, 'total_tokens': 93, 'input_token_details': {}, 'output_token_details': {}}\n"
     ]
    },
    {
     "data": {
      "text/plain": "{'input_tokens': 32,\n 'output_tokens': 61,\n 'total_tokens': 93,\n 'input_token_details': {},\n 'output_token_details': {}}"
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "for msg in graph.get_state(config).values[\"messages\"]:\n",
    "    print(f\"-----{msg}\")\n",
    "    \n",
    "graph.get_state(config).values[\"messages\"][-1].usage_metadata"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T03:25:33.341542Z",
     "start_time": "2024-11-11T03:25:33.323842Z"
    }
   },
   "id": "2d5a27d9be8d55d8",
   "execution_count": 65
  },
  {
   "cell_type": "markdown",
   "source": [],
   "metadata": {
    "collapsed": false
   },
   "id": "480425c31ffecf8c"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "[CheckpointTuple(config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef9fdc9-c26a-62dc-8002-0514c17b51d4'}}, checkpoint={'v': 1, 'ts': '2024-11-11T03:25:33.317363+00:00', 'id': '1ef9fdc9-c26a-62dc-8002-0514c17b51d4', 'channel_values': {'messages': [HumanMessage(content='what is my name?', additional_kwargs={}, response_metadata={}, id='f3ded638-1e1a-4e9a-ac6f-e8f4b31c9f26'), AIMessage(content=\"I'm sorry, but I don't have access to your personal information, including your name. To protect your privacy and security, it's best not to share such details unless you choose to. If you'd like, you can tell me your name, and I'll do my best to assist you!\", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 61, 'prompt_tokens': 32, 'total_tokens': 93, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'qwen-max', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-05043726-3a29-4b40-854a-b55793c237c9-0', usage_metadata={'input_tokens': 32, 'output_tokens': 61, 'total_tokens': 93, 'input_token_details': {}, 'output_token_details': {}})], 'conversation_store': 'conversation_store'}, 'channel_versions': {'__start__': '00000000000000000000000000000002.0.9672475799290258', 'messages': '00000000000000000000000000000003.0.4441918600306628', 'start:call_model': '00000000000000000000000000000003.0.050818238954257966', 'call_model': '00000000000000000000000000000004.0.8712219854554467', 'conversation_store': '00000000000000000000000000000004.0.6017460432390153'}, 'versions_seen': {'__input__': {}, '__start__': {'__start__': '00000000000000000000000000000001.0.2280310000242768'}, 'call_model': {'start:call_model': '00000000000000000000000000000002.0.7778425807413173'}, 'conversation_store': {'call_model': '00000000000000000000000000000003.0.9501619673309787'}}, 'pending_sends': []}, metadata={'source': 'loop', 'writes': {'conversation_store': None}, 'step': 2, 'parents': {}}, parent_config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef9fdc9-c261-6c4a-8001-1fd22b35d8b2'}}, pending_writes=[]),\n CheckpointTuple(config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef9fdc9-c261-6c4a-8001-1fd22b35d8b2'}}, checkpoint={'v': 1, 'ts': '2024-11-11T03:25:33.313915+00:00', 'id': '1ef9fdc9-c261-6c4a-8001-1fd22b35d8b2', 'channel_values': {'messages': [HumanMessage(content='what is my name?', additional_kwargs={}, response_metadata={}, id='f3ded638-1e1a-4e9a-ac6f-e8f4b31c9f26'), AIMessage(content=\"I'm sorry, but I don't have access to your personal information, including your name. To protect your privacy and security, it's best not to share such details unless you choose to. If you'd like, you can tell me your name, and I'll do my best to assist you!\", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 61, 'prompt_tokens': 32, 'total_tokens': 93, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'qwen-max', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-05043726-3a29-4b40-854a-b55793c237c9-0', usage_metadata={'input_tokens': 32, 'output_tokens': 61, 'total_tokens': 93, 'input_token_details': {}, 'output_token_details': {}})], 'call_model': 'call_model'}, 'channel_versions': {'__start__': '00000000000000000000000000000002.0.9672475799290258', 'messages': '00000000000000000000000000000003.0.4441918600306628', 'start:call_model': '00000000000000000000000000000003.0.050818238954257966', 'call_model': '00000000000000000000000000000003.0.9501619673309787'}, 'versions_seen': {'__input__': {}, '__start__': {'__start__': '00000000000000000000000000000001.0.2280310000242768'}, 'call_model': {'start:call_model': '00000000000000000000000000000002.0.7778425807413173'}}, 'pending_sends': []}, metadata={'source': 'loop', 'writes': {'call_model': {'messages': AIMessage(content=\"I'm sorry, but I don't have access to your personal information, including your name. To protect your privacy and security, it's best not to share such details unless you choose to. If you'd like, you can tell me your name, and I'll do my best to assist you!\", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 61, 'prompt_tokens': 32, 'total_tokens': 93, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'qwen-max', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-05043726-3a29-4b40-854a-b55793c237c9-0', usage_metadata={'input_tokens': 32, 'output_tokens': 61, 'total_tokens': 93, 'input_token_details': {}, 'output_token_details': {}})}}, 'step': 1, 'parents': {}}, parent_config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef9fdc9-8017-6a6a-8000-1d7e82fcacc4'}}, pending_writes=[('895ef9b8-8726-83e0-856c-17ccde00d148', 'conversation_store', 'conversation_store')]),\n CheckpointTuple(config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef9fdc9-8017-6a6a-8000-1d7e82fcacc4'}}, checkpoint={'v': 1, 'ts': '2024-11-11T03:25:26.362970+00:00', 'id': '1ef9fdc9-8017-6a6a-8000-1d7e82fcacc4', 'channel_values': {'messages': [HumanMessage(content='what is my name?', additional_kwargs={}, response_metadata={}, id='f3ded638-1e1a-4e9a-ac6f-e8f4b31c9f26')], 'start:call_model': '__start__'}, 'channel_versions': {'__start__': '00000000000000000000000000000002.0.9672475799290258', 'messages': '00000000000000000000000000000002.0.6400277830995701', 'start:call_model': '00000000000000000000000000000002.0.7778425807413173'}, 'versions_seen': {'__input__': {}, '__start__': {'__start__': '00000000000000000000000000000001.0.2280310000242768'}}, 'pending_sends': []}, metadata={'source': 'loop', 'writes': None, 'step': 0, 'parents': {}}, parent_config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef9fdc9-8012-622c-bfff-88b12881c763'}}, pending_writes=[('8ee434e3-1bf0-8651-3a6f-249a027e1799', 'call_model', 'call_model'), ('8ee434e3-1bf0-8651-3a6f-249a027e1799', 'messages', AIMessage(content=\"I'm sorry, but I don't have access to your personal information, including your name. To protect your privacy and security, it's best not to share such details unless you choose to. If you'd like, you can tell me your name, and I'll do my best to assist you!\", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 61, 'prompt_tokens': 32, 'total_tokens': 93, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'qwen-max', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-05043726-3a29-4b40-854a-b55793c237c9-0', usage_metadata={'input_tokens': 32, 'output_tokens': 61, 'total_tokens': 93, 'input_token_details': {}, 'output_token_details': {}}))]),\n CheckpointTuple(config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef9fdc9-8012-622c-bfff-88b12881c763'}}, checkpoint={'v': 1, 'ts': '2024-11-11T03:25:26.360724+00:00', 'id': '1ef9fdc9-8012-622c-bfff-88b12881c763', 'channel_values': {'__start__': {'messages': [{'type': 'user', 'content': 'what is my name?'}]}}, 'channel_versions': {'__start__': '00000000000000000000000000000001.0.2280310000242768'}, 'versions_seen': {'__input__': {}}, 'pending_sends': []}, metadata={'source': 'input', 'writes': {'__start__': {'messages': [{'type': 'user', 'content': 'what is my name?'}]}}, 'step': -1, 'parents': {}}, parent_config=None, pending_writes=[('ff575a46-ed6e-1e6c-7412-ddbd1008914d', 'messages', [{'type': 'user', 'content': 'what is my name?'}]), ('ff575a46-ed6e-1e6c-7412-ddbd1008914d', 'start:call_model', '__start__')])]"
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "checkpoint_tuples = [c async for c in memory_saver.alist(config)]\n",
    "checkpoint_tuples"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T03:25:33.355699Z",
     "start_time": "2024-11-11T03:25:33.344952Z"
    }
   },
   "id": "4da4b92e585c594c",
   "execution_count": 66
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
